/********************************************************/
/*	Author:		gong_libin			*/
/*	Date:		2017_11_01			*/
/*	File:		CmRedis.h			*/
/********************************************************/

#ifndef	_CMREDIS_H
#define	_CMREDIS_H

#include <r3c/r3c.h>
#include "CmGlobal.h"

typedef	std::string	CMSTRING_C;

class CCmRedis : public r3c::CRedisClient
{
public:
	CCmRedis(CMSTRING_C& rCCluster) : CRedisClient(rCCluster) {}
	virtual ~CCmRedis() {}

	/**
	int list_nodes(std::vector<struct NodeInfo>* nodes_info, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Try to clear all data in cluster
	// To clear only a node, set ctor's parameter `nodes` to a single node for standalone mode
	void flushall(std::vector<std::pair<std::string, std::string> >* results) throw (r3c::CRedisException);

	// key value
	bool key_type(const std::string& key, std::string* key_type, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool exists(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool expire(const std::string& key, uint32_t seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Evaluate scripts using the Lua interpreter built
	const r3c::RedisReplyHelper eval(const std::string& key, const std::string& lua_scripts, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	const r3c::RedisReplyHelper eval(const std::string& key, const std::string& lua_scripts, const std::vector<std::string>& parameters, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	const r3c::RedisReplyHelper evalsha(const std::string& key, const std::string& sha1, const std::vector<std::string>& parameters, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Success returns the remaining time to live of a key that has a timeout
	// Returns -2 if the key does not exist
	// Returns -1 if the key exists but has no associated expire
	int ttl(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	void set(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool setnx(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	void setex(const std::string& key, const std::string& value, uint32_t expired_seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool setnxex(const std::string& key, const std::string& value, uint32_t expired_seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool get(const std::string& key, std::string* value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t mget(const std::vector<std::string>& keys, std::vector<std::string>* values,
		std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	void mset(const std::map<std::string, std::string>& kv_map,
		std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool del(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t incrby(const std::string& key, int64_t increment, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// incrby and expire
	// If incrby return value equal to expired_increment, then set expired seconds for key with the given seconds
	// In general, expired_increment should be equal to increment.
	//
	// example (100 seconds):
	// incrby(key, 10, 10, 100);
	int64_t incrby(const std::string& key, int64_t increment, int64_t expired_increment, uint32_t expired_seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Return the cursor, not support cluster mode
	int64_t scan(int64_t cursor, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t scan(int64_t cursor, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t scan(int64_t cursor, const std::string& pattern, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t scan(int64_t cursor, const std::string& pattern, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// list
	int llen(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool lpop(const std::string& key, std::string* value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int lpush(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int lpush(const std::string& key, const std::vector<std::string>& values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int lrange(const std::string& key, int64_t start, int64_t end, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool ltrim(const std::string& key, int64_t start, int64_t end, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool rpop(const std::string& key, std::string* value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int rpush(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int rpush(const std::string& key, const std::vector<std::string>& values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int rpushx(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// hash
	bool hdel(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hmdel(const std::string& key, const std::vector<std::string>& fields, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hexists(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hlen(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hset(const std::string& key, const std::string& field, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hsetex(const std::string& key, const std::string& field, const std::string& value, uint32_t timeout_seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hsetnx(const std::string& key, const std::string& field, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hsetnxex(const std::string& key, const std::string& field, const std::string& value, uint32_t timeout_seconds, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool hget(const std::string& key, const std::string& field, std::string* value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t hincrby(const std::string& key, const std::string& field, int64_t increment, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	void hmincrby(const std::string& key, const std::vector<std::pair<std::string, int64_t> >& increments, std::vector<int64_t>* values=NULL, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	void hmset(const std::string& key, const std::map<std::string, std::string>& map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hmget(const std::string& key, const std::vector<std::string>& fields, std::map<std::string, std::string>* map, bool keep_null=false, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hgetall(const std::string& key, std::map<std::string, std::string>* map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hstrlen(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hkeys(const std::string& key, std::vector<std::string>* fields, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int hvals(const std::string& key, std::vector<std::string>* vals, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the cursor
	int64_t hscan(const std::string& key, int64_t cursor, std::map<std::string, std::string>* map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t hscan(const std::string& key, int64_t cursor, int count, std::map<std::string, std::string>* map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t hscan(const std::string& key, int64_t cursor, const std::string& pattern, std::map<std::string, std::string>* map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t hscan(const std::string& key, int64_t cursor, const std::string& pattern, int count, std::map<std::string, std::string>* map, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// set
	// Returns the number of elements that were added to the set,
	// not including all the elements already present into the set.
	int sadd(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int sadd(const std::string& key, const std::vector<std::string>& values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the cardinality (number of elements) of the set, or 0 if key does not exist.
	int scard(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool sismember(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int smembers(const std::string& key, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	bool spop(const std::string& key, std::string* value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int spop(const std::string& key, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the number of random members
	int srandmember(const std::string& key, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the number of members that were removed from the set, not including non existing members.
	int srem(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int srem(const std::string& key, const std::vector<std::string>& values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the cursor
	int64_t sscan(const std::string& key, int64_t cursor, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t sscan(const std::string& key, int64_t cursor, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t sscan(const std::string& key, int64_t cursor, const std::string& pattern, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t sscan(const std::string& key, int64_t cursor, const std::string& pattern, int count, std::vector<std::string>* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// sort set
	int zrem(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zrem(const std::string& key, const std::vector<std::string>& fields, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zadd(const std::string& key, const std::string& field, int64_t score, r3c::ZADDFLAG flag=r3c::Z_NS, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zadd(const std::string& key, const std::map<std::string, int64_t>& map, r3c::ZADDFLAG flag=r3c::Z_NS, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zcard(const std::string& key, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zcount(const std::string& key, int64_t min, int64_t max , std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zincrby(const std::string& key, const std::string& field, int64_t increment, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Both start and stop are zero-based indexes, where 0 is the first element, 1 is the next element and so on.
	// They can also be negative numbers indicating offsets from the end of the sorted set,
	// with -1 being the last element of the sorted set, -2 the penultimate element and so on.
	// Return number of elements
	int zrange(const std::string& key, int64_t start, int64_t end, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zrevrange(const std::string& key, int64_t start, int64_t end, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns all the elements in the sorted set at key with a score between min and max (including elements with score equal to min or max).
	int zrangebyscore(const std::string& key, int64_t min, int64_t max, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zrevrangebyscore(const std::string& key, int64_t min, int64_t max, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// The optional LIMIT argument can be used to only get a range of the matching elements (similar to SELECT LIMIT offset, count in SQL).
	// Keep in mind that if offset is large, the sorted set needs to be traversed for offset elements before getting to the elements to return,
	// which can add up to O(N) time complexity.
	int zrangebyscore(const std::string& key, int64_t min, int64_t max, int64_t offset, int64_t count, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zrevrangebyscore(const std::string& key, int64_t max, int64_t min, int64_t offset, int64_t count, bool withscores, std::vector<std::pair<std::string, int64_t> >* vec, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Add command
	int zremrangebyrank(const std::string& key, int64_t start, int64_t end, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Return -1 if field not exists
	int zrank(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int zrevrank(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zscore(const std::string& key, const std::string& field, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// Returns the cursor
	int64_t zscan(const std::string& key, int64_t cursor, std::vector<std::pair<std::string, int64_t> >* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zscan(const std::string& key, int64_t cursor, int count, std::vector<std::pair<std::string, int64_t> >* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zscan(const std::string& key, int64_t cursor, const std::string& pattern, std::vector<std::pair<std::string, int64_t> >* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);
	int64_t zscan(const std::string& key, int64_t cursor, const std::string& pattern, int count, std::vector<std::pair<std::string, int64_t> >* values, std::pair<std::string, uint16_t>* which=NULL) throw (r3c::CRedisException);

	// raw command, binary unsafe
	const redisReply* redis_command(int excepted_reply_type, std::pair<std::string, uint16_t>* which, const std::string* key, const char* command, const std::string& command_string) throw (r3c::CRedisException);
	// raw command, binary safe
	const redisReply* redis_command(int excepted_reply_type, std::pair<std::string, uint16_t>* which, const std::string* key, const char* command, int argc, const char* argv[], const size_t* argv_len) throw (r3c::CRedisException);
	*/

protected:

private:

};

#endif /* _CMREDIS_H */
